/**
  ******************************************************************************
  * @file           : certificateManager.h
  * @author         : sally
  * @brief          : None
  * @attention      : None
  * @date           : 24-12-18
  ******************************************************************************
  */

#ifndef CERTIFICATEMANAGER_H
#define CERTIFICATEMANAGER_H

#include <QDebug>
#include "config.h"
#include <iostream>
#include <map>
#include <memory>
#include <openssl/err.h>
#include <openssl/types.h>
#include <openssl/x509.h>
#include <stdio.h>
#include <unistd.h>
#include <utils/deleter.h>
#include <vector>

BIGNUM* generate_large_serial_number();

#ifdef SINGLETON_PATTERN
#define certManger CertificateManager::instance()

//单例模式的类
class CertificateManager
{
public:
    static CertificateManager& instance()
    {
        static CertificateManager instance;
        return instance;
    }

    ~CertificateManager();

    X509_REQ* generateCSR(const std::map<std::string, std::string>& subjectInfo, EVP_PKEY* userKey);
    bool saveCertificate(X509* cert, const std::string& filePath);
    bool savePrivateKey(EVP_PKEY* pkey, const std::string& filePath);
    bool safeSavePrivateKey(EVP_PKEY* pkey, const std::string& filePath, const std::string& passwd);
    bool verifyCert(X509* PeerCert, EVP_PKEY** PeerPubkey, EVP_PKEY* RTA_PubKey);
    // 读取已经存在的公私钥文件，如果存在且是有效的，则不会创建新的证书和公私钥，否则则需要创建
    bool Extract_and_verify_privKey_is_valid(EVP_PKEY** evp_pri, const std::string& privateKeyPath);

    bool ExtractVerifyPKCertIsValid(EVP_PKEY** evp_pubKey, const std::string& privateKeyPath);
    std::string readPemFile(const std::string& filePath);
    // 将读取到的字符串转换为X509类型，即将证书字符串转换为证书
    X509* PemCharToX509(char* buffer, ssize_t bytesRead);
    std::vector<unsigned char> convertX509ToDER(X509* cert);
    X509* convertDERToX509(const unsigned char* der_data, size_t der_size);
    // 从证书中提取公钥
    EVP_PKEY* getPubKeyFromCert(X509* cert);
    bool loadCACertificate(EVP_PKEY** CA_pubKey, const std::string& certificatePath);
    CertificateManager(const CertificateManager&) = delete;
    bool VerficateCSR(X509_REQ* csr);

    bool X509_REQ_to_DER(X509_REQ* req, std::vector<unsigned char>& der_data);

    CertificateManager& operator=(const CertificateManager&) = delete;

private:
    // void handleOpenSSLErrors() { ERR_print_errors_fp(stderr); }
    explicit CertificateManager();

private:
    // EVP_PKEY* caPubKey_;
    // X509* caCertificate_;
};

#else
class CertificateManager
{
public:
    explicit CertificateManager();
    ~CertificateManager();

    X509* generateCert(EVP_PKEY* PLiPublickey,
                       EVP_PKEY* rtaPrivateKey,
                       int validityDays,
                       const std::map<std::string, std::string>& issuerInfo,
                       const std::map<std::string, std::string>& subjectInfo);
    bool saveCertificate(X509* cert, const std::string& filePath);
    bool savePrivateKey(EVP_PKEY* pkey, const std::string& filePath);
    // 读取已经存在的公私钥文件，如果存在且是有效的，则不会创建新的证书和公私钥，否则则需要创建
    bool Extract_and_verify_privKey_is_valid(EVP_PKEY** evp_pri, const std::string& privateKeyPath);
    std::string readPemFile(const std::string& filePath);
    // 将读取到的字符串转换为X509类型，即将证书字符串转换为证书
    X509* PemCharToX509(char* buffer, ssize_t bytesRead);
    // 从证书中提取公钥
    EVP_PKEY* getPubKeyFromCert(X509* cert);

private:
    void handleOpenSSLErrors() { ERR_print_errors_fp(stderr); }

private:
};
#endif

#endif //CERTIFICATEMANAGER_H
